package com.example.result.explore

import android.util.Log
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Color.*
import androidx.compose.ui.graphics.Color.Companion.Blue
import androidx.compose.ui.graphics.Color.Companion.Cyan
import androidx.compose.ui.graphics.Color.Companion.Red
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp

@Composable
fun TextShow() {
    LazyColumn {
        item { BoldText() }
        item { TextShadow() }
        item { MultipleStylesInText() }
        item {
            val gradientColors = listOf(Cyan, Blue, Red /*...*/)

            Text(
                text = "listOf(Cyan, LightBlue, Purple /*...*/)",
                style = TextStyle(
                    brush = Brush.linearGradient(
                        colors = gradientColors
                    )
                )
            )
        }
        item {
            Text(
                text = buildAnnotatedString {
                    append("Do not allow people to dim your shine\n")
                    withStyle(
                        SpanStyle(
                            brush = Brush.linearGradient(
                                colors = listOf(Red, Blue, Cyan)
                            )
                        )
                    ) {
                        append("because they are blinded.")
                    }
                    append("\nTell them to put some sunglasses on.")
                }
            )
        }
        val rainbowColors = listOf(Red, Blue, Cyan)
        item {
            val brush = Brush.linearGradient(colors = rainbowColors)

            buildAnnotatedString {
                withStyle(
                    SpanStyle(
                        brush = brush, alpha = .5f
                    )
                ) {
                    append("Text in ")
                }
                withStyle(
                    SpanStyle(
                        brush = brush, alpha = 1f
                    )
                ) {
                    append("Compose ❤️")
                }
            }
        }
        item {
            BasicMarqueeSample()
        }
        item {
            TextParagraphStyle()
        }
        item {
            Text(
                text = "lineHeightStyle = LineHeightStyle(\n" +
                        "                alignment = LineHeightStyle.Alignment.Center,\n" +
                        "                trim = LineHeightStyle.Trim.None\n" +
                        "            )",
                style = LocalTextStyle.current.merge(
                    TextStyle(
                        lineHeight = 2.5.em,
                        platformStyle = PlatformTextStyle(
                            includeFontPadding = false
                        ),
                        lineHeightStyle = LineHeightStyle(
                            alignment = LineHeightStyle.Alignment.Center,
                            trim = LineHeightStyle.Trim.None
                        )
                    )
                )
            )
        }
        item {
            OverflowedText()
        }
        item {
            PartiallySelectableText()
        }
        item {
            AnnotatedClickableText()
        }
    }

}

@Composable
fun AnnotatedClickableText() {
    val annotatedText = buildAnnotatedString {
        append("Click ")

        // We attach this *URL* annotation to the following content
        // until `pop()` is called
        pushStringAnnotation(
            tag = "URL", annotation = "https://developer.android.com"
        )
        withStyle(
            style = SpanStyle(
                color = Blue, fontWeight = FontWeight.Bold
            )
        ) {
            append("here")
        }
        pop()
        rangeText()

    }
    var url by remember {
        mutableStateOf("")
    }
    if (url.isNotEmpty()) {
        Text(text = url)
    }
    ClickableText(text = annotatedText, onClick = { offset ->
        // We check if there is an *URL* annotation attached to the text
        // at the clicked position
        annotatedText.getStringAnnotations(
            tag = "URL", start = offset, end = offset
        ).firstOrNull()?.let { annotation ->
            // If yes, we log its value
            Log.d("Clicked URL", annotation.item)
            url = annotation.item
        }
    })
}

@Composable
private fun AnnotatedString.Builder.rangeText() {
    append("no react ")
    pushStringAnnotation(
        tag = "URL", annotation = "https://developer.android.google.cn"
    )
    append("other can click")
    pop()
}

@Composable
fun PartiallySelectableText() {
    SelectionContainer {
        Column {
            Text("This text is selectable")
            Text("This one too")
            Text("This one as well")
            DisableSelection {
                Text("But not this one")
                Text("Neither this one")
            }
            Text("But again, you can select this one")
            Text("And this one too")
        }
    }
}

@Composable
fun OverflowedText() {
    Text("Hello Compose ".repeat(50), maxLines = 2, overflow = TextOverflow.Ellipsis)
}

@Composable
fun TextParagraphStyle() {
    Text(
        buildAnnotatedString {
            withStyle(style = ParagraphStyle(lineHeight = 30.sp)) {
                withStyle(style = SpanStyle(color = Blue)) {
                    append("Hello\n")
                }
                withStyle(
                    style = SpanStyle(
                        fontWeight = FontWeight.Bold, color = Red
                    )
                ) {
                    append("World\n")
                }
                append("Compose")
            }
        }
    )
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun BasicMarqueeSample() {
    // Marquee only animates when the content doesn't fit in the max width.
    Column(Modifier.width(400.dp)) {
        Text(
            "Learn about why it's great to use Jetpack Compose",
            modifier = Modifier.basicMarquee(),
            fontSize = 50.sp
        )
    }
}

@Composable
fun BoldText() {
    Text("Hello World", fontWeight = FontWeight.Bold)
}

@Composable
fun TextShadow() {
    val offset = Offset(5.0f, 10.0f)
    Text(
        text = "Hello world!",
        style = TextStyle(
            fontSize = 24.sp,
            shadow = Shadow(
                color = Blue, offset = offset, blurRadius = 3f
            )
        )
    )
}

@Composable
fun MultipleStylesInText() {
    Text(
        buildAnnotatedString {
            withStyle(style = SpanStyle(color = Blue)) {
                append("H")
            }
            append("ello ")

            withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Red)) {
                append("W")
            }
            append("orld")
        }
    )
}